using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;
using System.Reflection;

namespace PS.Framework.Remoting
{
	public class RemotingClient<T> where T: class
	{
		#region Fields
		#endregion

		#region Properties

		private InterfaceConnectionState _connectionState;
		/// <summary>
		/// gets or sets the connection state
		/// </summary>
		public InterfaceConnectionState ConnectionState
		{
			get { return _connectionState; }
			set { _connectionState = value; }
		}

		private RemotingInterface<T> _interface;
		/// <summary>
		/// gets or sets the logger interface
		/// </summary>
		public RemotingInterface<T> Interface
		{
			get { return _interface; }
			set { _interface = value; }
		}


        private string _sHostName;
        /// <summary>
        /// gets or sets the servers host name
        /// </summary>
        public string HostName
        {
            get { return _sHostName; }
            set { _sHostName = value; }
        }

        private int _iPort;
        /// <summary>
        /// gets or sets the servers port
        /// </summary>
        public int Port
        {
            get { return _iPort; }
            set { _iPort = value; }
        }

        private string _RemoteInterface;
        /// <summary>
        /// gets or sets the remote interface
        /// </summary>
        public string RemoteInterface
        {
            get { return _RemoteInterface; }
            set { _RemoteInterface = value; }
        }

        private string _sProtocolRef;
        /// <summary>
        /// gets or sets the protocol type
        /// </summary>
        public string ProtocolRef 
        {
            get { return _sProtocolRef; }
            set { _sProtocolRef = value; }
        }
        
        
		#endregion

		#region Construction / Destruction

		#endregion

		#region Methods

		/// <summary>
		/// Create a connection to the interface server
		/// </summary>
		public void Connect()
		{
			try
			{
        		// check if the interface is allready connected
				if (this._interface != null || this._connectionState != InterfaceConnectionState.NotConnected)
					// if we are connected we must disconnect
					this.Disconnect();

				this._interface = (RemotingInterface<T>)Activator.GetObject(typeof(RemotingInterface<T>), string.Concat(this._sProtocolRef, "://", this._sHostName, ":", this._iPort, "/", this._RemoteInterface));

                // call the check connection method
				// so the interface will be really initialized
				this.CheckConnection();
				// set the connection state to connected
				this._connectionState = InterfaceConnectionState.Connected;
			}
			catch
			{
				// there was an error so we are not connected
				this._connectionState = InterfaceConnectionState.ConnectionError;
			}
		}

		/// <summary>
		/// Method to disconnect from interface server
		/// </summary>
		public void Disconnect()
		{
			try
			{
				if (this._interface != null)
				{
					this._interface = null;
				}
			}
			finally
			{
				this._connectionState = InterfaceConnectionState.NotConnected;
			}
		}

		/// <summary>
		/// Method to check the connection
		/// </summary>
		public void CheckConnection()
		{
			try
			{
				if (this._interface == null)
					this._connectionState = InterfaceConnectionState.NotConnected;
				else
				{
					this._interface.ToString();
					this._connectionState = InterfaceConnectionState.Connected;
				}
			}
			catch
			{
				this._connectionState = InterfaceConnectionState.ConnectionError;
			}
		}

		#endregion
	}
}
